// API请求封装
import axios, { AxiosError, AxiosRequestConfig } from "axios";
import { ElMessage } from "element-plus";
import {
  getToken,
  clearAuth,
  isTokenExpired,
  saveDebugLog,
} from "@/utils/auth";

// 创建一个标志，防止多次显示过期提示
let isShowingExpiredMessage = false;
// 创建一个标志，防止多次显示网络错误提示
let isShowingNetworkError = false;

// 自定义网络错误类型
interface NetworkError extends Error {
  name: string;
  config?: AxiosRequestConfig;
  request?: any;
}

// 创建 axios 实例
const request = axios.create({
  baseURL: "/",
  timeout: 10000,
  headers: {
    "Content-Type": "application/json",
  },
});

// 请求拦截器，添加token
request.interceptors.request.use(
  (config) => {
    // 检查token是否存在
    const token = getToken();
    if (token && config.headers) {
      // 检查token是否过期
      if (isTokenExpired()) {
        // 记录token过期信息到调试日志
        saveDebugLog("TOKEN_EXPIRED_INTERCEPTOR", {
          url: config.url,
          method: config.method,
          time: new Date().toLocaleString(),
        });

        // 防止多次显示过期提示
        if (!isShowingExpiredMessage) {
          isShowingExpiredMessage = true;

          // token已过期，清除认证信息并提示用户
          clearAuth();
          ElMessage.error("登录已过期，请重新登录");

          // 使用延迟，避免在请求处理过程中跳转
          setTimeout(() => {
            // 使用相对路径，避免清空控制台
            if (window.location.pathname !== "/") {
              window.location.href = "/merchant/debug"; // 跳转到调试页面而不是首页
            }
            isShowingExpiredMessage = false;
          }, 1000);
        }

        return Promise.reject(new Error("登录已过期"));
      }

      // 添加token到请求头
      config.headers.Authorization = `Bearer ${token}`;
    }
    return config;
  },
  (error) => {
    console.error("请求拦截器错误:", error);
    saveDebugLog("REQUEST_INTERCEPTOR_ERROR", error.message);
    return Promise.reject(error);
  }
);

// 响应拦截器，统一处理响应
request.interceptors.response.use(
  (response) => {
    // 打印响应数据，帮助调试
    console.log("API响应状态:", response.status);
    console.log("API响应头:", response.headers);
    console.log("API响应数据:", response.data);

    // 检查响应结构
    if (response.data) {
      console.log("响应数据结构:", {
        hasData: !!response.data.data,
        hasContent: response.data.data?.content ? true : false,
        hasRecords: response.data.data?.records ? true : false,
        hasList: response.data.data?.list ? true : false,
        hasItems: response.data.data?.items ? true : false,
        pagination:
          response.data.data?.totalElements !== undefined
            ? {
                total: response.data.data.totalElements,
                size: response.data.data.size,
                number: response.data.data.number,
                totalPages: response.data.data.totalPages,
              }
            : "无分页信息",
      });
    }

    return response;
  },
  (error: AxiosError) => {
    // 处理错误响应
    if (error.response) {
      const { status, data } = error.response;
      console.error(`API错误响应 [${status}]:`, data);
      saveDebugLog("API_ERROR_RESPONSE", {
        status,
        data,
        url: error.config?.url,
        method: error.config?.method,
      });

      // 处理401错误（未授权）
      if (status === 401) {
        // 记录401错误到调试日志
        saveDebugLog("UNAUTHORIZED_ERROR", {
          url: error.config?.url,
          method: error.config?.method,
          time: new Date().toLocaleString(),
        });

        // 防止多次显示过期提示
        if (!isShowingExpiredMessage) {
          isShowingExpiredMessage = true;

          clearAuth();
          ElMessage.error("登录已过期，请重新登录");

          // 使用延迟，避免在请求处理过程中跳转
          setTimeout(() => {
            // 使用相对路径，避免清空控制台
            if (window.location.pathname !== "/") {
              window.location.href = "/merchant/debug"; // 跳转到调试页面而不是首页
            }
            isShowingExpiredMessage = false;
          }, 1000);
        }

        return Promise.reject(new Error("登录已过期"));
      }

      // 处理403错误（禁止访问）
      if (status === 403) {
        saveDebugLog("FORBIDDEN_ERROR", {
          url: error.config?.url,
          method: error.config?.method,
        });
        ElMessage.error("没有权限访问该资源");
        return Promise.reject(new Error("权限不足"));
      }

      // 处理404错误（资源不存在）
      if (status === 404) {
        saveDebugLog("NOT_FOUND_ERROR", {
          url: error.config?.url,
          method: error.config?.method,
        });
        ElMessage.error("请求的资源不存在");
        return Promise.reject(new Error("资源不存在"));
      }

      // 处理500错误（服务器错误）
      if (status >= 500) {
        saveDebugLog("SERVER_ERROR", {
          url: error.config?.url,
          method: error.config?.method,
          status,
        });
        ElMessage.error("服务器错误，请稍后再试");
        return Promise.reject(new Error("服务器错误"));
      }
    } else if (error.request) {
      // 请求发出但没有收到响应 (网络连接失败)
      console.error("网络连接失败:", error.request);
      saveDebugLog("NETWORK_ERROR", {
        url: error.config?.url,
        method: error.config?.method,
      });

      // 防止多次显示网络错误提示
      if (!isShowingNetworkError) {
        isShowingNetworkError = true;

        ElMessage({
          message: "网络连接失败，请检查您的网络连接或服务器状态",
          type: "error",
          duration: 5000,
          showClose: true,
          onClose: () => {
            isShowingNetworkError = false;
          },
        });

        // 自动清除状态，避免卡死
        setTimeout(() => {
          isShowingNetworkError = false;
        }, 5000);
      }

      // 构建带有更多信息的错误对象
      const networkError = new Error("网络连接失败") as NetworkError;
      networkError.name = "NetworkError";
      networkError.config = error.config;
      networkError.request = error.request;

      return Promise.reject(networkError);
    } else {
      // 请求设置时发生错误
      console.error("请求配置错误:", error.message);
      saveDebugLog("REQUEST_CONFIG_ERROR", {
        message: error.message,
        url: error.config?.url,
        method: error.config?.method,
      });
      ElMessage.error("请求错误，请稍后再试");
    }

    console.error("API请求错误:", error);
    return Promise.reject(error);
  }
);

// 创建一个带有重试机制的请求函数
export const requestWithRetry = async (
  config: AxiosRequestConfig,
  retries = 2,
  delay = 1000
) => {
  try {
    return await request(config);
  } catch (err) {
    const error = err as NetworkError;
    // 只对网络错误进行重试
    if (error.name === "NetworkError" && retries > 0) {
      console.log(
        `请求失败，${delay / 1000}秒后重试，剩余重试次数: ${retries}`
      );
      await new Promise((resolve) => setTimeout(resolve, delay));
      return requestWithRetry(config, retries - 1, delay * 2);
    }
    throw error;
  }
};

export default request;
